<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { HemisphereLight, PerspectiveCamera, Scene, WebGLRenderer } from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

// 创建一个场景
const scene = new Scene();
// 创建一个相机
// fov: 视野角度，视野角度就是无论在什么时候，你所能在显示器上看到的场景的范围，它的单位是角度(与弧度区分开)
// aspect: 长宽比，也就是你用一个物体的宽除以它的高的值。比如说，当你在一个宽屏电视上播放老电影时，可以看到图像仿佛是被压扁的
// near: 近截面
// far: 远截面
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建一个渲染器，并把背景设置成透明
const renderer = new WebGLRenderer({ alpha: true });
// 设置渲染器尺寸,对性能较敏感的程序可以设置一个较小的值来减少渲染的尺寸
// 如果你希望保持应用程序的尺寸，但是以较低的分辨率渲染，可以将该函数的第三个参数设置为false
// 这样你再修改尺寸时并不会影响应用程序的尺寸而是转而影响他的分辨率
renderer.setSize(window.innerWidth, window.innerHeight);
let canvas = ref<HTMLDivElement>();
onMounted(() => {
  // 判断一下是否拿到了组件中的元素节点
  if (canvas.value) {
    // 将渲染器的dom元素添加到组件的节点中
    canvas.value.appendChild(renderer.domElement)
  }else{
    console.log("获取不到节点对象");
  }
})

// 创建加载进度变量
let progress = ref<number>(0)
// 加载模型
const loader = new GLTFLoader();
loader.load('mecha_roe_deer.glb', glb => {
  scene.add(glb.scene)
}, evet => {
  // 在加载回调函数中获取当前载入模型进度
  let pn = Number((evet.loaded / evet.total).toFixed(2))
  // 更新加载进度变量
  setTimeout(() => { progress.value = pn * 100 }, 270);
})
// 加个半球光源（经过测试这个效果最好）
const light = new HemisphereLight(0xffffff, 0x080820, 15);
scene.add(light)
// 创建一个拖拽控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 开启惯性开关，能够让拖拽手感更顺滑
controls.enableDamping = true;
// 设置一下相机位置
camera.position.set(0, 5, 5);
// 调整一下场景角度（让我这个模型正面对着我）
scene.rotateY(Math.PI);
// 渲染场景
function animate(): void {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}
animate();
</script>

<template>
  <div id="canvas" ref="canvas">
    <v-progress-circular v-if="progress != 100" class="center" color="primary" indeterminate :size="80" :width="10">
      {{ progress + "%" }}
    </v-progress-circular>
  </div>
</template>

<style scoped>
#canvas {
  position: relative;
}

.center {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
}
</style>
